<?php

namespace App\Http\Controllers\Admin;

use App\Classes\EasyTree;
use App\Http\Controllers\AdminController;
use App\Jobs\SetAdminLog;
use App\Models\AdminGroup;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Http\Request;

use App\Http\Requests;

class AdminGroupController extends AdminController
{
    /**
     * 验证条件数组
     * @var array
     */
    protected $verifyFactor = [
        'lv'            => 'required|integer',
        'name'          => 'required|unique:admin_group'
    ];

    /**
     * 分组管理
     * @return $this
     */
    public function getIndex()
    {
        //获取权限内的分组
        $adminGroup = AdminGroup::where('lv', $this->user->id === 1 ? '>=' : '>', $this->user->lv)
            ->orderBy('lv', 'asc')
            ->paginate(15);
        return view('admin.admin-group')->with(['adminGroup' => $adminGroup]);
    }

    /**
     * 添加分组
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function getAdd()
    {
        return view('admin.admin-group-add');
    }
    public function postAdd(Request $request)
    {
        //验证
        $this->verifyFactor['lv'] .= $this->user->id !== 1 ? '|min:'.($this->user->lv+1) : '|min:'.($this->user->lv);
        $verifyMsg = $this->verification($request->input());
        if ($verifyMsg)
        {
            return redirect()->action('Admin\AdminGroupController@getAdd')->withInput()->withErrors($verifyMsg);
        }
        //整理数据
        $request->merge([
            'permissions'          => '1,28,29,30'
        ]);

        //Create
        if (AdminGroup::create($request->input()))
        {
            //setLog
            $this->setLog('create', NULL, json_encode($request->except('_token')));
            return ShowMsg('success', getLang('Tips', 'createSuccess'), action('Admin\AdminGroupController@getIndex'), 1);
        }

        return ShowMsg('error', getLang('Tips', 'createFail'), action('Admin\AdminGroupController@getIndex'), 1);
    }

    /**
     * 修改分组
     * @param $id
     * @return $this|\Illuminate\Http\RedirectResponse
     */
    public function getEdit($id)
    {
        $adminGroup = AdminGroup::find($id);
        if (empty($adminGroup))
            return redirect()->back();
        if ($this->verifyIllegality($adminGroup->lv))
            return ShowMsg('error', getLang('Tips', 'illegal'), action('Admin\AuthController@getLogout'), 3);

        return view('admin.admin-group-edit')->with(['adminGroup' => $adminGroup]);
    }
    public function postEdit(Request $request, $id)
    {
        //验证
        $this->verifyFactor['lv'] .= $this->user->id !== 1 ? '|min:'.($this->user->lv+1) : '|min:'.($this->user->lv);
        if ($id == 1)
            $this->verifyFactor['lv'] .= '|size:1';
        $this->verifyFactor['name'] .= ',name,'.$id;
        $verifyMsg = $this->verification($request->input());
        if ($verifyMsg)
        {
            return redirect()->action('Admin\AdminGroupController@getEdit', ['id' => $id])->withErrors($verifyMsg);
        }

        //修改前的值
        $origin = AdminGroup::find($id)->toArray();
        //Update
        if (AdminGroup::where('id', $id)->update($request->except('_token')))
        {
            //setLog
            $this->setLog('update', json_encode($origin), json_encode($request->except('_token')));
            return ShowMsg('success', getLang('Tips', 'updateSuccess'), action('Admin\AdminGroupController@getEdit', ['id' => $id]), 1);
        }
        return ShowMsg('error', getLang('Tips', 'updateFail'), action('Admin\AdminGroupController@getEdit', ['id' => $id]), 1);

    }

    /**
     * 删除分组
     * @param $id
     * @return $this
     */
    public function getDel($id)
    {
        if ((int)$id === 1)
            return ShowMsg('error', getLang('Tips', 'groupNotDelete'),'',1);
        //获取用户
        $adminGroup = AdminGroup::find($id);
        $origin = $adminGroup->toArray();
        if (!empty($adminGroup))
        {
            if ($this->verifyIllegality($adminGroup->lv))
                return ShowMsg('error', getLang('Tips', 'illegal'), action('Admin\AuthController@getLogout'), 1);
            if ($adminGroup->delete())
            {
                //setLog
                $this->setLog('delete', json_encode($origin));
                //删除分组下的用户
                User::where('groupID',$id)->delete();
                return ShowMsg('success', getLang('Tips', 'deleteSuccess'),'',1);
            }
        }
        return ShowMsg('error', getLang('Tips', 'illegal'),'',1);
    }

    /**
     * 权限管理
     * @param $id
     * @return $this
     */
    public function getGroupPermissions($id)
    {
        if ((int)$id === 1)
            return ShowMsg('warning', getLang('Tips', 'groupNotConfig'),'',1);
        //整理目录
        $thisGroup = AdminGroup::find($id);
        if ($this->verifyIllegality($thisGroup->lv))
            return ShowMsg('error', getLang('Tips', 'illegal'), action('Admin\AuthController@getLogout'), 1);
        $permissions = explode(',',$thisGroup->permissions);
        $menu = $this->menu;
        foreach ($menu as $k=>$v)
        {
            $menu[$k]->level        =   $this->getLevel($v->id, $menu);
            $menu[$k]->checked      =   in_array($v->id, $permissions) ? ' checked' : '';
            $menu[$k]->pesName      =   $v->parentID == 0 ? '<b>'.$v->name.'</b>' : $v->name;
        }

        $template = "<tr>
                        <td>\$spacer<input type='checkbox' name='checked[]' value='\$v->id' level='\$v->level' \$v->checked/>&nbsp;&nbsp;&nbsp;&nbsp;\$v->pesName</td>
                    </tr>";

        //创建目录树HTML
        $tree = new EasyTree($menu);
        $tree = $tree->setTemplate($template)->getTree();

        return view('admin.admin-group-permissions')->with(['tree' => $tree]);
    }

    public function postGroupPermissions(Request $request, $id)
    {
        $thisGroup = AdminGroup::find($id);
        $origin = $thisGroup->toArray();
        //验证是否越级
        if ($this->verifyIllegality($thisGroup->lv))
            return ShowMsg('error', getLang('Tips', 'illegal'), action('Admin\AuthController@getLogout'), 1);
        //验证提交的菜单是否有权限修改
        if ($this->user->groupID != 1)
        {
            $userGroup = $request->group[$this->user->groupID];
            if (empty(array_diff(explode(',', $userGroup->permissions), $request->input('checked'))))
                return ShowMsg('error', getLang('Tips', 'illegal'), action('Admin\AuthController@getLogout'), 1);
        }
        $thisGroup->permissions = $request->has('checked') ? implode(',', $request->input('checked')) : '1';
        if ($thisGroup->save())
        {
            //setLog
            $this->setLog('updateJN', json_encode($origin), json_encode($request->except('_token')));
            return ShowMsg('success', getLang('Tips', 'updateSuccess'),'',1);
        }
        return ShowMsg('error', getLang('Tips', 'updateFail'),'',1);
    }

    /**
     * 验证是否越级操作
     * @param $lv
     * @return bool
     */
    private function verifyIllegality($lv)
    {
        if ($this->user->id != 1 && $this->user->lv >= $lv)
            return true;
        return false;
    }

    /**
     * 获取菜单深度
     * @param $id
     * @param $menu
     * @param int $i
     * @return int
     */
    private function getLevel($id, $menu, $i=0) {
        foreach($menu as $v){
            if($v->id == $id)
            {
                if($v->parentID == '0') return $i;
                $i++;
                return $this->getLevel($v->parentID, $menu, $i);
            }
        }
    }

    /**
     * 记录日志
     * @param string$type 类型 create update delete
     * @param json null $origin 事件发生前
     * @param json null $ending 事件发生后
     */
    private function setLog($type, $origin = NULL, $ending = NULL)
    {
        switch ($type)
        {
            case 'create':
                $event = [
                    'msg'   =>  'adminGroup.create',
                    'type'  =>  'Create'
                ];
                break;
            case 'update':
                $event = [
                    'msg'   =>  'adminGroup.update',
                    'type'  =>  'Update'
                ];
                break;
            case 'delete':
                $event = [
                    'msg'   =>  'adminGroup.delete',
                    'type'  =>  'Delete'
                ];
                break;
            case 'updateJN':
                $event = [
                    'msg'   =>  'adminGroup.updateJN',
                    'type'  =>  'Update'
                ];
                break;
        }
        //push to queue
        $geoIP = geoip()->getLocation();
        $this->dispatch(new SetAdminLog($this->user->id, $geoIP, $event['msg'], Carbon::now(), $event['type'], $origin, $ending));
    }
}
